<!DOCTYPE html>
<html>
    <head>

        <link rel="canonical" href="http://www.jointjs.com/" />
        <meta name="description" content="Create interactive diagrams in JavaScript easily. JointJS plugins for ERD, Org chart, FSA, UML, PN, DEVS, LDM diagrams are ready to use." />
        <meta name="keywords" content="JointJS, JavaScript, diagrams, diagramming library, UML, charts" />

        <link href="http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700" rel="stylesheet" type="text/css" />
        <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">

        <link rel="stylesheet" href="css/tutorial.css" />
        <link rel="stylesheet" href="../node_modules/prismjs/themes/prism.css">


        <!-- Dependencies: -->
        <script src="../node_modules/jquery/dist/jquery.js"></script>
        <script src="../node_modules/lodash/lodash.js"></script>
        <script src="../node_modules/backbone/backbone.js"></script>


        <link rel="stylesheet" type="text/css" href="../build/joint.min.css" />
        <script type="text/javascript" src="../build/joint.min.js"></script>

        <title>JointJS - JavaScript diagramming library - Getting started.</title>

    </head>
    <body class="language-javascript tutorial-page">

        <script>
            SVGElement.prototype.getTransformToElement = SVGElement.prototype.getTransformToElement || function (toElement) {
                return toElement.getScreenCTM().inverse().multiply(this.getScreenCTM());
            };
        </script>

        <div id="hierarchy" class="tutorial">

            <h2>Tips on hierarchical diagrams</h2>

            <p>
                JointJS provides a facility to create hierarchy in your diagrams. The API is simple and
                contains three methods and two properties dealing with parent-child relationships between elements.
                The methods are <a href="/docs/jointjs/v1.0/joint.html#dia.Element.prototype.embed" target="_top">embed()</a>,
                <a href="/docs/jointjs/v1.0/joint.html#dia.Element.prototype.unembed" target="_top">unembed()</a> and
                <a href="/docs/jointjs/v1.0/joint.html#dia.Element.prototype.getEmbeddedCells" target="_top">getEmbeddedCells()</a>.
                The properties are <code>embeds</code> and <code>parent</code> (Please refer to the <strong>Nesting</strong>
                section
                of the <a href="/docs/jointjs/v1.0/joint.html#dia.Element" target="_top">joint.dia.Element</a> model reference).
            </p>

            <p>This tutorial shows how to take advantage of these methods in order to implement three functionalities
                common to parent-child relationships: <a href="#parent-restriction" target="_self"><strong>child movement restriction to
                        the parent area</strong></a>,
                <a href="#parent-expand" target="_self"><strong>expanding parent area to cover its children</strong></a> and
                <a href="#reparenting" target="_self"><strong>reparenting</strong></a>.
            </p>

            <h3 id="parent-restriction">Restricting child movement to the parent area</h3>

            <p>The goal is to restrict the movement of an element embedded in a parent in order disallow
                the user to drag the element outside the parent element area.
            <p>
            <p>The trick here is to detect when the child element bounding box gets outside the bounding box
                of the parent and revert the child position if that happens.</p>

            <p class="note">Try to move the child element outside the parent element area.</p>

            <div id="paper-parent-restriction"></div>
            <script type="text/javascript" src="js/hierarchy-parent-restriction.js"></script>
            <pre data-src="js/hierarchy-parent-restriction.js"></pre>

            <h3 id="parent-expand">Expanding parent area to cover its children</h3>

            <p>This section shows how to make the parent element automatically resizable so that it coveres
                its children.</p>

            <p>Again, we'll react on the <code>change:position</code> event on the graph but this time we resize the parent
                element based on the position and size of its children. We also store the original position and size of the
                parent element so that we can shrink the parent element back if the child element we manipulate
                fits into the original parent element area.</p>

            <p class="note">Try to move the child element outside the parent element area and see how the
                parent element automatically expands/shirnks.</p>

            <div id="paper-parent-expand"></div>
            <script type="text/javascript" src="js/hierarchy-parent-expand.js"></script>
            <pre data-src="js/hierarchy-parent-expand.js" style="height: 1700px"></pre>


            <h3 id="reparenting">Reparenting</h3>

            <p>Another useful technique when dealing with parent-child relationships is being able to drop an element
                above another element and let the element below become a new parent of the dropped element. This way
                we alow the user to change the parentage via the UI.</p>

            <p>First, we register a handler for the <code>cell:pointerdown</code> event on the paper that is triggered
                whenever a mousedown (touchstart) above a cell is emitted. This is where the dragging begins. In this
                handler,
                we unembed the dragged element if it was a child of a parent. Note that we also show the dragged element
                above all the other cells (<code>toFront()</code>) so that we always see it in the front while dragging.
                Second, we register a handler for the <code>cell:pointerup</code> event which is triggered when we
                drop the dragged element. In this handler, we find all the cells that are below the center of the
                dragged element. In this example, we pick the first one that is not the dragged element itself
                and make it a new parent of the dragged element. If you have more than one level of hierarchy in
                your application, you might want to find an element the most in the front (by looking at the <code>z</code>
                property) instead. We left this out of this example for simplicity.</p>

            <p class="note">Try to move the <i>El B</i> over <i>El A</i>, then move the <i>El A</i>. You should see
                the <i>El B</i> moves as well as it became a child of <i>El A</i>.</p>

            <div id="paper-reparenting"></div>
            <script type="text/javascript" src="js/hierarchy-reparenting.js"></script>
            <pre data-src="js/hierarchy-reparenting.js" style="height: 1100px"></pre>

        </div>

        <script src="../node_modules/prismjs/prism.js"></script>

    </body>
</html>
